// Copyright 2010 Google Inc. All Rights Reserved.

package com.hisense.settings.channel;

import com.android.settings.R;
import com.google.android.tv.mediadevices.Device;
import com.google.android.tv.mediadevices.LoadChannelListTask;
import com.google.android.tv.mediadevices.MediaDevicesIntents;
import com.google.android.tv.mediadevices.UpdateAvailableChannelsTask;
import com.google.android.tv.model.Channel;
import com.google.android.tv.model.ChannelListAdapter;
import com.google.android.tv.model.ChannelSource;
import com.google.android.tv.provider.MediaDevicesContract.ChannelSources;
import com.google.android.tv.resources.GtvResources;
import com.google.android.tv.ui.ChannelSearchKeyListener;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.StrictMode;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.EditText;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.android.tv.mediadevices.MediaDevicesServiceConnection;
import com.google.android.tv.mediadevices.IMediaDevicesService;
import com.google.android.tv.mediadevices.MediaDevicesConstants;
import android.content.IntentFilter;
import android.os.RemoteException;
import android.content.BroadcastReceiver;
/**
 * Activity which sets the selected channels.
 *
 * @author justinkoh@google.com (Justin Koh)
 * @author mlindner@google.com (Mark Lindner)
 */
public final class EditChannelLineupActivity extends ListActivity {
    // STOPSHIP: set this to false
    private static final boolean DEBUG = true;
    private static final String LOG_TAG = "EditChannelLineupActivity";

    private Button mButtonEnableAll;
    private Button mButtonDisableAll;

    private ProgressBar mProgressBar;
    private ListView mListView;
    private TextView mEmptyView;
    private EditText mFilterText;
    private MyChannelListAdapter mAdapter;
    private MyLoadChannelListTask mLoadChannelsTask;
    private MyUpdateAvailableChannelsTask mUpdateChannelsTask;
    private List<ChannelSource> mChannelSourceList;
    private boolean mShouldLoadList;
    private boolean mResumed;
private BroadcastReceiver mDeviceChangeReceiver;
    private MediaDevicesServiceConnection mServiceConnection;
    private IMediaDevicesService mService;
	private Device mDevice;
	
	
    private static final boolean ENABLE_STRICT_MODE = false;

    private static UpdateAvailableChannelsTask mStaticUpdateChannelsTask;

    private static UpdateAvailableChannelsTask getUpdateAvailableChannelsTask() {
        return mStaticUpdateChannelsTask;
    }

    private static void setUpdateAvailableChannelsTask(
            UpdateAvailableChannelsTask updateChannelsTask) {
        mStaticUpdateChannelsTask = updateChannelsTask;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (ENABLE_STRICT_MODE) {
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .build());
        }
				
        Window window = getWindow();
        window.setLayout(WindowManager.LayoutParams.FILL_PARENT,
                WindowManager.LayoutParams.WRAP_CONTENT);
        setContentView(R.layout.edit_channels);
        setupFilterText();
        setupButtons();
        setupList();
        // Automatically pass keypresses within the list view to the filter
        // field.
        mListView.setOnKeyListener(new ChannelSearchKeyListener(mFilterText));
        // Not worth overriding XML just for this.
        mListView.setCacheColorHint(0);
        mListView.requestFocus();
        //int activityWidth = getResources().getDimensionPixelSize(R.dimen.activity_width);
        int activityWidth = 1060;
        getWindow().setLayout(activityWidth, ViewGroup.LayoutParams.WRAP_CONTENT);

        // Make the dialog as tall as possible.
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.height = WindowManager.LayoutParams.MATCH_PARENT;
        getWindow().setAttributes(lp);

        Context resourceContext = new GtvResources(this).getResourceContext();
        mChannelSourceList = getChannelSourceList();
    }

	private void updateDevice() {
        if (mService != null) {
            try {
                Device newDevice = mService.getDeviceById(mDevice.getId());
                if (newDevice != null) {
                    mDevice = newDevice;
//                    setTitle(getString(R.string.device_settings_label, mDevice.getLabel()));
                }
            } catch (RemoteException re) {
                Log.w(LOG_TAG, "Failed to get device: " + mDevice.getId(), re);
            }
        }
    }
	
    private Bitmap getIconForChannelSource(int source) {
        for (ChannelSource channelSource : mChannelSourceList) {
            if (channelSource.getSource() == source) {
                return channelSource.getIcon();
            }
        }
        return null;
    }

    private List<ChannelSource> getChannelSourceList() {
        ArrayList<ChannelSource> channelSourceList = new ArrayList<ChannelSource>();

        Cursor cursor = getContentResolver().query(ChannelSources.CHANNEL_SOURCES_URI,
                ChannelSources.CHANNEL_SOURCES_PROJECTION, null, null, null);
        if (cursor != null) {
            while (cursor.moveToNext()) {
                int source = cursor.getInt(ChannelSources.INDEX_INDEX);
                String title = cursor.getString(ChannelSources.NAME_INDEX);
                byte[] iconBytes = cursor.getBlob(ChannelSources.ICON_INDEX);
                Bitmap icon = iconBytes == null ? null :
                      BitmapFactory.decodeStream(new ByteArrayInputStream(iconBytes));
                channelSourceList.add(new ChannelSource(source, title, icon));
            }
            cursor.close();
        }

        return channelSourceList;
    }

    @Override
    public void onResume() {
        if (DEBUG) Log.d(LOG_TAG, "onResume()");
        mResumed = true;

        mUpdateChannelsTask = (MyUpdateAvailableChannelsTask) getUpdateAvailableChannelsTask();
        if (mUpdateChannelsTask != null) {
            mUpdateChannelsTask.setParentActivity(this);
        }

        if (DEBUG) Log.d(LOG_TAG, "mUpdateChannelsTask=" + mUpdateChannelsTask);
        super.onResume();

        if (mUpdateChannelsTask != null) {
            if (DEBUG) Log.d(LOG_TAG, "update is still running");
            // An update task is still running from a previous onPause(); show
            // the progress bar, and set the flag so we know to load the
            // channel list when it completes.
            mShouldLoadList = true;
            setBusy(true);
        } else {
            if (DEBUG) Log.d(LOG_TAG, "loading the channel list");
            // Start loading the channel list.
            mLoadChannelsTask = new MyLoadChannelListTask(this, getDeviceId());
            mLoadChannelsTask.execute();
        }
    }

    @Override
    protected void onPause() {
        if (DEBUG) Log.d(LOG_TAG, "onPause");
        mResumed = false;

        mUpdateChannelsTask = new MyUpdateAvailableChannelsTask(this);
        setUpdateAvailableChannelsTask(mUpdateChannelsTask);
        mUpdateChannelsTask.execute(getDeviceId());
        super.onPause();
    }

    @Override
    protected void onStop() {
        if (DEBUG) Log.d(LOG_TAG, "onStop");
        mResumed = false;
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        if (mUpdateChannelsTask != null) {
            mUpdateChannelsTask.setParentActivity(null);
        }
        if (DEBUG) Log.d(LOG_TAG, "onDestroy");
        super.onDestroy();
    }

    private void setupButtons() {
        mButtonEnableAll = (Button) findViewById(R.id.button_enable);
		mButtonEnableAll.setVisibility(View.INVISIBLE);
        mButtonEnableAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setAllChannelsEnabled(true);
            }
        });

        mButtonDisableAll = (Button) findViewById(R.id.button_disable);
		mButtonDisableAll.setVisibility(View.INVISIBLE);
        mButtonDisableAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setAllChannelsEnabled(false);
            }
        });
    }

    private void setupList() {
        mListView = getListView();
        mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
        mEmptyView = (TextView) findViewById(R.id.empty);
        mAdapter = new MyChannelListAdapter(this);
        setListAdapter(mAdapter);

//        setTitle(getString(R.string.edit_channels_activity, getDevice().getLabel()));
        mListView.setItemsCanFocus(false);
        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        mListView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                // Toggle the state.
                Channel channel = mAdapter.getItem(position);
                channel.setEnabled(!channel.isEnabled());
                mAdapter.notifyList();
            }
        });

        setBusy(true);
    }

    private void setupFilterText() {
        mFilterText = (EditText) findViewById(R.id.filter);
		mFilterText.setVisibility(View.INVISIBLE);
        mFilterText.addTextChangedListener(new TextWatcher() {
            @Override
            public void afterTextChanged(Editable s) {
                filterText(mFilterText.getText());
            }

            @Override
            public void beforeTextChanged(
                    CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(
                    CharSequence s, int start, int before, int count) {}
        });
    }

    private void filterText(CharSequence filterText) {
        Filterable filter = ((Filterable) mListView.getAdapter());
        filter.getFilter().filter(filterText);
        // Reset the scroll position up to the top of the list when filtering.
        mListView.post(new Runnable() {
                @Override
                public void run() {
                    if (getListAdapter().getCount() > 0) {
                        mListView.setSelection(0);
                    }
                }
            });
    }

    private Device getDevice() {
	final Intent intent = getIntent();
	Log.d(LOG_TAG, "MediaDevicesIntents.getDeviceId(getIntent())&&&&"+MediaDevicesIntents.getDevice(getIntent()));
        return MediaDevicesIntents.getDevice(getIntent());
    }
	private String getDeviceId() {
	String deviceid="com.marvell.willowtv.controller.device.TUNER";
	Log.d(LOG_TAG, "MediaDevicesIntents.getDeviceId(getIntent())&&&&"+MediaDevicesIntents.getDevice(getIntent()));
        return deviceid;
    }

    private void setAllChannelsEnabled(boolean enabled) {
        final int count = mAdapter.getCount();
        for (int i = 0; i < count; ++i) {
            Channel channel = mAdapter.getItem(i);
            channel.setEnabled(enabled);
        }
        mAdapter.notifyList();
    }

    private void setControlsEnabled(boolean enabled) {
        mFilterText.setEnabled(enabled);
        mButtonEnableAll.setEnabled(enabled);
        mButtonDisableAll.setEnabled(enabled);
        mListView.setEnabled(enabled);
    }

    /**
     * Adapter for presenting the list of channels.
     */
    private class MyChannelListAdapter extends ChannelListAdapter {
        private LayoutInflater mInflater;

        public MyChannelListAdapter(Context context) {
            super(context);
            mInflater = LayoutInflater.from(context);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;
            if (view == null) {
                view = mInflater.inflate(R.layout.edit_channels_item, parent,
                        false);
            }

            final Channel channel = getItem(position);

            CheckedTextView titleView = (CheckedTextView) view.findViewById(
                    android.R.id.text1);
            titleView.setText(getDisplayString(channel));
            titleView.setChecked(channel.isEnabled());

            ImageView iconView = (ImageView) view.findViewById(R.id.channel_image_view);
            iconView.setImageBitmap(channel.getIcon());

            ImageView sourceView = (ImageView) view.findViewById(R.id.channel_source_view);
            int source = channel.getSource();
            sourceView.setImageBitmap(getIconForChannelSource(source));

            return view;
        }

        public void notifyList() {
            notifyDataSetChanged();
        }
    }

    /**
     * AsyncTask to populate the channel list view.
     */
    private class MyLoadChannelListTask extends LoadChannelListTask {
        public MyLoadChannelListTask(Context context, String deviceId) {
            super(context, deviceId, LoadChannelListTask.FLAG_LOAD_CHANNEL_ICONS);
        }

        @Override
        protected void onPreExecute() {
            if (DEBUG) Log.d(LOG_TAG, "starting load list");
            mAdapter.clear();
            setControlsEnabled(false);
        }

        @Override
        protected void onPostExecute(List<Channel> result) {
            mProgressBar.setVisibility(View.GONE);
            mAdapter.setItems(result);
            boolean haveResults = !result.isEmpty();
            setControlsEnabled(haveResults);
            if (haveResults) {
                mListView.setVisibility(View.VISIBLE);
                mListView.setSelection(0);
                mListView.requestFocus();
            }
            mLoadChannelsTask = null;

            // Set the empty view after we've loaded the list. This prevents
            // the momentary flash of the empty view while the list is being
            // loaded.
            mListView.setEmptyView(mEmptyView);
            // We use a different message for the empty view depending on
            // whether there were results or not; if there *were* results,
            // then we only have an empty view if the filter text doesn't
            // match any of the channels.
            mEmptyView.setText(haveResults ? R.string.channels_no_match
                    : R.string.empty_channel_lineup);
        }
    }

    private void updateFinished() {
        if (EditChannelLineupActivity.this.mResumed) {
            if (DEBUG) Log.d(LOG_TAG, "mShouldLoadList=" + mShouldLoadList);
            if (mShouldLoadList) {
                mShouldLoadList = false;
                // Start loading the channel list.
                mLoadChannelsTask = new MyLoadChannelListTask(
                        EditChannelLineupActivity.this, getDeviceId());
                mLoadChannelsTask.execute();
            } else {
                setVisible(false);
                setBusy(false);
            }
        }
    }

    private void setBusy(boolean busy) {
        setControlsEnabled(!busy);
        mListView.setVisibility(busy ? View.GONE : View.VISIBLE);
        mProgressBar.setVisibility(busy ? View.VISIBLE : View.GONE);
    }

    private class MyUpdateAvailableChannelsTask extends UpdateAvailableChannelsTask {
        private Set<Channel> mDisabledChannels;
        private EditChannelLineupActivity mParentActivity;

        MyUpdateAvailableChannelsTask(Context context) {
            super(context);
            mParentActivity = EditChannelLineupActivity.this;
        }

        public void setParentActivity(EditChannelLineupActivity parentActivity) {
            mParentActivity = parentActivity;
        }

        @Override
        protected void onPreExecute() {
/*            Intent intent = MediaDevicesIntents.createLineupChannelsUpdatingIntent(
                    EditChannelLineupActivity.this, getDevice());
            if (intent != null) {
                startService(intent);
            } else {
                Log.w(LOG_TAG,
                      "No component to handle LINEUP_CHANNELS_UPDATING for " +
                      getDevice());
            }
*/
            // Create a set of channels that are unchecked (disabled).
            mDisabledChannels = new HashSet<Channel>();
            int count = mAdapter.getUnfilteredCount();
            for (int i = 0; i < count; ++i) {
                final Channel channel = mAdapter.getUnfilteredItem(i);
                if (!channel.isEnabled()) {
                    mDisabledChannels.add(channel);
                }
            }
        }

        @Override
        protected boolean isChannelAvailable(final Channel channel,
                final Map<String, String> extraUriParams) {
            return !mDisabledChannels.contains(channel);
        }

        @Override
        protected void onPostExecute(Integer result) {
            if (DEBUG) Log.d(LOG_TAG, "update completed; is resumed? "
                    + EditChannelLineupActivity.this.mResumed);
            mUpdateChannelsTask = null;

/*            Intent intent = MediaDevicesIntents.createLineupEditedIntent(
                    EditChannelLineupActivity.this, getDevice());
            if (intent != null) {
                startService(intent);
            } else {
                Log.w(LOG_TAG, "No component to handle LINEUP_EDITED for " + getDevice());
            }
*/
            // Notify the system that a lineup configuration change has occurred.
            MediaDevicesIntents.broadcastLineupConfigurationChange(
                    EditChannelLineupActivity.this, getDeviceId());

            setUpdateAvailableChannelsTask(null);

            if (mParentActivity != null) {
                mParentActivity.updateFinished();
            }
        }
    }
}
